package main

import (
	"goroutine/Customer"
	"goroutine/Sushi"
	"goroutine/cook"
	"log"
	"math/rand"
)

//检查顾客是否吃饱
func checkcustomer(Customerwanted chan bool, m int, Customerexit chan bool) {
	for i := 0; i < m; i++ {
		<-Customerwanted
	}
	close(Customerwanted)
	Customerexit <- true
	close(Customerexit)
}

//食材上限
var matrial_upper = 50

//检查食材是否用完
func checkmaterial(exit chan bool) {
	defer close(exit)
	for {
		if cook.Usedmaterial == matrial_upper {
			exit <- true
			//close(exit)
			break
		}

	}
}

//检查厨师是否下班
func checkcook(cookfinished chan bool, n int, exit chan bool) {
	for i := 0; i < n; i++ {
		<-cookfinished
	}
	exit <- true
	close(exit)
	close(cookfinished)
}
func main() {
	/*
		初始化参数
		n:厨师个数
		m:顾客个数
		workload:厨师上限工作量
		wanted:顾客上限食量
		Customerwanted:每个顾客吃饱信号
		Customers:顾客切片
		Cookworkload:厨师是否达到工作量
		cooks:厨师切片
		Customerexit:所有顾客吃饱信号
		cookexit：所有厨师下班信号
		materialexit:材料用完信号
	*/
	n := 10
	m := 50
	workload := 20
	wanted := 200
	Customerwanted := make(chan bool, m)
	Customers := make([]Customer.Customer, m)
	Cookworkload := make(chan bool, n)
	cooks := make([]cook.Cook, n)
	Customerexit := make(chan bool, 1)
	cookexit := make(chan bool, 1)
	materialexit := make(chan bool, 1)
	t := make(Sushi.Transporter, 10)
	//初始化厨师
	for i := 0; i < n; i++ {
		a := rand.Intn(100)
		w := rand.Intn(workload)
		//w = 1
		co := cook.Getcooker(i, a, w)
		cooks[i] = co
		go cooks[i].PutSushi(t, Cookworkload)
	}
	//初始化顾客
	for i := 0; i < m; i++ {
		a := rand.Intn(100)
		want := rand.Intn(wanted)
		cus := Customer.GetCustomer(i, want, a)
		Customers[i] = cus
		go Customers[i].TakeSushi(t, Customerwanted)
	}
	//检查退出条件
	go checkcook(Cookworkload, n, cookexit)
	go checkmaterial(materialexit)
	go checkcustomer(Customerwanted, m, Customerexit)
	flag := false
	//LOOP:
	//检查三个退出条件
	for {
		select {
		case <-Customerexit:
			log.Println("所有顾客已经吃饱了！！！")
			Customerexit = nil
			flag = true
			//break LOOP
		case <-cookexit:
			log.Println("所有厨师已经下班了！！！！")
			cookexit = nil
			flag = true
			//break LOOP
		case <-materialexit:
			materialexit = nil
			flag = true
			log.Println("食材已经用完了!!!!!!")
			//break LOOP
		default:

		}
		if flag {
			break
		}
	}
	//打印厨师信息
	for i := 0; i < n; i++ {
		s := cooks[i].ToString()
		log.Println(s)
	}
	//打印顾客信息
	for i := 0; i < m; i++ {
		s := Customers[i].ToString()
		log.Println(s)
	}
	log.Println("关闭店铺@@@@@@@@@@")
}
